home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * *
- * sortfile.c version 1.0 of 1 Januari 1989 (C) L.J.M. de Wit 1989 *
- * *
- * This software may be used and distributed freely if not used commercially *
- * and the originator (me) is mentioned in the source (just leave this 9 line *
- * header intact). *
- * *
- ******************************************************************************
- *
- * sortfile.c: stdio replacement for Atari ST
- *
- * This replacement is added both to speed up the normal stdio offered by
- * Lattice C, and to repair a bug with open() (fopen() ?) that is in the
- * standard library (version 3.03: try opening & closing 20 files, your
- * program bombs when you try to open a new file, even though the old ones
- * have been closed).
- *
- * Note that this package is not complete (no flushbuf, filbuf, printf etc.)
- * but this wasn't the intent anyway; furthermore, the allocation of buffers
- * takes place when a file is opened, rather than when it is first read/written
- * (as in a standard stdio package).
- */
-
- #include <stdio.h>
- #include <osbind.h>
- #include <fcntl.h>
- #include "sortmain.h"
- #include "sortfile.h"
-
- #undef Fwrite
- #define Fwrite fixwrite /* Fix for Fwrite bug */
-
- static int buflen; /* Default buffer length */
-
- static int lopen();
- static int fixwrite();
-
- #ifdef BESTIO
-
- void bestio(size) /* Initializes stdin/stdout */
- int size;
- {
- char *iobuffer[2]; /* stdin/stdout buffer ptrs */
-
- buflen = size;
- iobuffer[0] = (char *)Malloc(buflen);
- iobuffer[1] = (char *)Malloc(buflen);
- if (iobuffer[0] == (char *)-1 || iobuffer[1] == (char *)-1) {
- error("memory allocation failed\n",(char *)0);
- }
- stdin->_ptr = stdin->_base = iobuffer[0];
- stdin->_rcnt = buflen;
- stdin->_flag = _IOREAD;
- stdin->_file = 0;
- stdin->_size = buflen;
-
- stdout->_ptr = stdout->_base = iobuffer[1];
- stdout->_wcnt = buflen;
- stdout->_flag = _IOWRT;
- stdout->_file = 1;
- stdout->_size = buflen;
- }
-
- void exit(code) /* Replaces standard exit */
- int code;
- {
- int i;
-
- for (i = 0; i < _NFILE; i++) {
- if (_iob[i]._flag != 0) { /* Stclose any open files */
- stclose(_iob+i);
- }
- }
- _exit(code); /* and _exit */
- }
-
- #else NOT BESTIO
-
- int _fmode = 0x8000; /* No translation, for speed*/
-
- #endif BESTIO
-
- FILE *stopen(filename,mode) /* Replaces fopen() */
- char *filename, *mode;
- {
- FILE *fp;
- int desc;
- int flag;
- int i;
-
- for (i = 0; i < _NFILE; i++) { /* Find first free entry */
- if (_iob[i]._flag == 0) {
- break;
- }
- }
- if (i < _NFILE) {
- fp = _iob + i; /* First free */
- } else {
- return (FILE *)0; /* All occupied */
- }
-
- if (!strcmp(mode,"w")) { /* Mode "w": write */
- desc = lopen(filename,O_WRONLY|O_CREAT|O_TRUNC);
- flag = _IOWRT;
- } else if (!strcmp(mode,"r")) { /* Mode "r": read */
- desc = lopen(filename,O_RDONLY);
- flag = _IOREAD;
- } else { /* Unknown mode */
- return (FILE *)0;
- }
-
- if (desc < 0) {
- return (FILE *)0; /* Lopen failed */
- } else {
- fp->_rcnt = fp->_wcnt = fp->_size = 0;
- fp->_ptr = fp->_base = (char *)0;
- fp->_file = desc;
- fp->_flag = flag;
- }
-
- return fp;
- }
-
- int stclose(fp) /* Replaces fclose() */
- FILE *fp;
- {
- int retco;
-
- if (fp->_flag & (_IORW|_IOWRT)) {
- stflush(fp); /* Flush an output stream */
- }
- retco = Fclose(fp->_file); /* Close file */
- if (fp->_base != (char *)0) {
- retco |= Mfree(fp->_base); /* Free allocated buffer */
- }
- fp->_base = (char *)0;
- fp->_flag = 0; /* Indicate entry is free */
-
- return retco;
- }
-
- int stflush(fp)
- FILE *fp;
- {
- if (fp->_size > fp->_wcnt) { /* Any data to be flushed ? */
- Fwrite(fp->_file,fp->_size-fp->_wcnt,fp->_base); /* Write it */
- fp->_ptr = fp->_base; /* re-init ptr */
- fp->_wcnt = fp->_size; /* and _wcnt */
- }
- }
-
- void stbuffer(fp,buf,size)
- FILE *fp;
- char *buf;
- int size;
- {
- fp->_ptr = fp->_base = buf;
- fp->_size = size;
- fp->_wcnt = size;
- fp->_rcnt = 0;
- }
-
- char *stgets(inbuf,size,fp) /* Replaces fgets() */
- char *inbuf;
- register int size;
- register FILE *fp;
- {
- register int todo, i, ntoread;
- register char *s, *t;
-
- if (fp->_base == (char *)0) {
- s = (char *)Malloc(buflen); /* Allocate buffer */
- stbuffer(fp,s,buflen);
- }
- if (size-- <= 0 || feof(fp)) { /* One for the '\0' */
- return (char *)0;
- }
-
- t = inbuf;
- s = fp->_ptr;
- ntoread = fp->_rcnt;
-
- for ( ; ; ) {
- todo = min(size,ntoread);
- for (i = 0; i < todo; i++) {
- if ((*t++ = *s++) == '\n') { /* Had a newline */
- i++;
- *t = '\0'; /* 0-terminate line */
- fp->_ptr = s;
- fp->_rcnt = ntoread - i;
- return inbuf;
- }
- }
- if ((size -= todo) <= 0) { /* All read */
- break;
- }
- ntoread = Fread(fp->_file,fp->_size,fp->_base); /* Read a buffer */
- s = fp->_base; /* Re-init ptr */
- if (ntoread <= 0) {
- fp->_flag |= _IOEOF;
- return (char *)0; /* End-of-file */
- }
- }
- fp->_rcnt = ntoread - todo;
- fp->_ptr = s;
- *t = '\0';
- return inbuf;
- }
-
- void stputs(inbuf,fp) /* Replaces fputs() */
- char *inbuf;
- register FILE *fp;
- {
- register int i, ntowrite;
- register char *s, *t;
-
- if (fp->_base == (char *)0) {
- s = (char *)Malloc(buflen); /* Allocate buffer */
- stbuffer(fp,s,buflen);
- }
- s = inbuf;
- t = fp->_ptr;
- ntowrite = fp->_wcnt;
-
- for ( ; ; ) {
- for (i = 0; i < ntowrite; i++) {
- if (*s == '\0') { /* Found 0 terminator */
- break;
- }
- *t++ = *s++;
- }
- if (*s == '\0') {
- fp->_wcnt = ntowrite - i;
- fp->_ptr = t;
- return;
- }
- Fwrite(fp->_file,t - fp->_base,fp->_base); /* Write a buffer */
- ntowrite = fp->_size;
- t = fp->_base; /* Re-init ptr */
- }
- }
-
- static int lopen(filename,mode) /* Simple open() replacement*/
- char *filename;
- int mode;
- {
- int fd;
-
- if (!(mode & O_TRUNC)) {
- fd = Fopen(filename,mode & (O_WRONLY|O_RDWR)); /* Open file */
- }
-
- if ((mode & O_TRUNC) || ((fd < 0) && (mode & O_CREAT))) {
- fd = Fcreate(filename,!(mode & (O_WRONLY|O_RDWR))); /* Create file */
- }
-
- return fd;
- }
-
- static int fixwrite(fd,len,buf)
- int fd, len;
- char *buf;
- {
- int total, piece = 0;
- char *top;
-
- if (fd != 1) {
- return gemdos(0x40,fd,len,buf);
- }
- for (total = 0, top = buf + len; len > 0; buf += piece, len -= piece) {
- if ((piece = len) > 32767) {
- piece = 32256;
- }
- total += gemdos(0x40,fd,piece,buf);
- }
- return total;
- }
-